package week7.ui;

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

import week7.hotel.Hotel;
import week7.hotel.Kamer;
import week7.intlist.IntegerList;

/**
 * Een TUI voor de klasse Hotel, er zijn meerdere commando's in deze TUI opgenomen.
 * @author R.Oost & W.Looge
 * @version 1.0
 */
public class HotelTUI {

    /**
     * Scanner op de standaard invoer
     */
    private Scanner in = new Scanner(System.in);
    
    /**
     * Het hotel waar de TUI op wordt toegepast
     */
    public Hotel hotel;
    
    /**
     * Lijst van alle commando's die worden gebruikt door de TUI
     */
    private List<Commando> commandos;
    
    /**
     * Boolean welke aangeeft of de methode moet afsluiten
     */
    private boolean ended = false;
    
    /**
     * Main methode, maakt een nieuw HotelTUI object en start dit.
     */
    public static void main(String[] args) {
        new HotelTUI().run();
    }
    
    /**
     * Constructor die de commandos opslaat in een lijst.
     */
    public HotelTUI() {
    	commandos = new ArrayList<Commando>();
    	commandos.add(new CommandoA());
    	commandos.add(new CommandoI());
    	commandos.add(new CommandoR());
    	commandos.add(new CommandoK());
    	commandos.add(new CommandoU());
    	commandos.add(new CommandoH());
    	commandos.add(new CommandoP());
    	commandos.add(new CommandoV());
    	commandos.add(new CommandoX());
    }
    
    /**
     * Start het programma, er wordt eerst een hotel opgezet met de naam Drienerburght. Daarna
     * wordt het menu met commando's weergegeven en kunnen er commando's worden uitgevoerd.
     */
    public void run() {
    	setUp();
        System.out.println("Hotelboekingssysteem Hotel " + hotel.getNaam());
        printMenu();
        while(!ended){
        	voerCommandoUit(leesCommando());
        }
        System.out.println("Systeem is succesvol afgesloten.");
    }
    
    //Initialiseer het hotel
    private void setUp() {
        hotel = new Hotel("Drienerburght", IntegerList.createIntegerList("[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20]"));
    }
    
    //Print het help menu
    private void printMenu() {
        System.out.println("Commando's:");
        
        int lengte = commandos.size();
        for(int x = 0; x < lengte; x++) {
        	System.out.println(commandos.get(x).getTeken() + commandos.get(x).getBeschrijving());
        }
    }
    
    //Lees de regel
    private String leesRegel(String prompt) {
        System.out.println("");
    	System.out.print(prompt); System.out.flush();
    	return in.nextLine();
    }
    
    //Lees het commando en sla het op in cmd
    private Scanner leesCommando() {
    	String regel = leesRegel("Commando: ");
    	while (regel.equals("")) {
    		regel = leesRegel("Commando: ");
    	}
    	if (regel.equals("")) {
    		return null;
    	} else {
    		return new Scanner(regel);
    	}
    }
    
    /**
     * Deze functie voert het commando uit dat wordt aangetroffen op de regel waar de Scanner actief is.
     * @param scan Een scanner op een regel met een commando (en argumenten) welke moet worden uitgevoerd.
     */
    private void voerCommandoUit(Scanner scan) {
    	char teken = 0;
        String par1 = null;
        String par2 = null;
        
        // Sla de variabelen op
        if(scan.hasNext())
            teken = scan.next().charAt(0); //Het eerste teken van de input
        if(scan.hasNext())
            par1 = scan.next();
    	if(scan.hasNext())
            par2 = scan.next(); 
    	
    	int lengte = commandos.size();
    	boolean uitgevoerd = false;
    	
        for(int x = 0; x < lengte; x++) {
        	if(commandos.get(x).kanUitvoeren(teken, par1, par2)) {
        		commandos.get(x).voerUit(par1, par2);
        		uitgevoerd = true;
        	}
        }
        
    	if (!uitgevoerd) System.out.println("Onbekende combinatie van parameters!");
    }
    
    //--------------------------------Commando's--------------------------------------
    
    //Kluisje activeren
    private class CommandoA extends Commando {
		public CommandoA() {
			super('a', 2, " wachtwoord naam .... activeer kluisje van gast");
		}

		@Override
		public void voerUit(String ww, String naam) {
        	Kamer k = hotel.getKamer(naam);							//Vind de kamer die bij deze naam hoort
            
        	if (k!=null) {//Bekend
        	 	k.getKluis().activeer(ww);							//Activeer kluis
        	 	if (k.getKluis().isActief()) {
        	 		System.out.println("De kluis van " + naam + " op " + k + " is succesvol geactiveerd.");
        	 	} else {
        	 		System.out.println("Activeren is mislukt!");
        	 	}
        	} else {//Onbekend
        		System.out.println("Deze gast is onbekend!");
        	}
		}
    }
    
    //Hulpmenu printen
    private class CommandoH extends Commando {
		CommandoH() {
			super('h', 0, " .................... hulp (dit menu)");
		}

		@Override
		public void voerUit(String par1, String par2) {
			printMenu();
		}
    }
    
    //Gast inchecken
    private class CommandoI extends Commando {
		CommandoI() {
			super('i', 2, " wachtwoord naam .... check gast in op naam");
		}

		@Override
		public void voerUit(String ww, String naam) {
        	if (hotel.checkin(ww, naam) != null){//Goed     					//Controleer of alles goed is gegaan
        		System.out.println("Gast " + naam + " is succesvol ingecheckt in " + hotel.getKamer(naam) + ".");
        	} else {//Fout
        		System.out.println("Inchecken mislukt!");
        	}
		}
    }
    
    //Kamer van een Gast vinden
    private class CommandoK extends Commando {

		CommandoK() {
			super('k', 1, " naam ............... vraag kamer van gast op");
		}

		@Override
		public void voerUit(String naam, String par2) {
        	Kamer k = hotel.getKamer(naam);							//Vind de kamer die bij deze naam hoort
            
        	if (k!=null) { //Bekend
        		System.out.println("Gast " + naam + " verblijft in " + k + ".");
        	} else { //Onbekend
        		System.out.println("Deze gast is onbekend!");
        	}
		}
    }
    
    //Status printen
    private class CommandoP extends Commando {
		CommandoP() {
			super('p', 0, " .................... print status");
		}

		@Override
		public void voerUit(String par1, String par2) {
			System.out.println(hotel.toString());
		}
    }
    
    //Rekening printen
    private class CommandoR extends Commando {

		protected CommandoR() {
			super('r', 2, " naam nachten ....... rekening van deze gast");
		}

		@Override
		public void voerUit(String naam, String nachtenstr) {
			//Zet nachtenstr om in een getal
			Scanner s = new Scanner(nachtenstr);
			if(s.hasNextInt()) {
				int nachten = s.nextInt();
				if (hotel.getRekening(naam, nachten, System.out) == null) {
					System.out.println("Deze gast hoeft niets te betalen of is onbekend!");
				}
			} else {
				System.out.println("Dat is geen getal!");
			}
			s.close();
		}
    }
    
    //Gast uitchecken
    private class CommandoU extends Commando {
		CommandoU() {
			super('u', 1, " naam ............... check gast uit op naam");
		}

		@Override
		public void voerUit(String naam, String par2) {
        	Kamer k = hotel.getKamer(naam);							//Vind de kamer die bij deze naam hoort
        	
        	if (k!=null){											//Kijk of de gast bestaat dmv return van getKamer()
        		k.getGast().checkuit();								//Check de gast uit
        		System.out.println("Gast " + naam + " is succesvol uitgecheckt.");
        	} else { //Fout
        		System.out.println("Gast " + naam + " is onbekend!");
        	}
		}
    }
    
    //Alle vrije kamers printen
    private class CommandoV extends Commando {
		CommandoV() {
			super('v', 0,  ".................... print vrije kamers");
		}

		@Override
		public void voerUit(String par1, String par2) {
			System.out.println("Vrije kamers:");
			List<Kamer> vrijekamers = hotel.getVrijeKamers();
			for(int x = 0; x < vrijekamers.size(); x++) {
				System.out.println("    " + vrijekamers.get(x)); // Print naam van de kamer
			}
		}
    }
    
    //Programma afsluiten
    private class CommandoX extends Commando {
		CommandoX() {
			super('x', 0, " .................... exit");
		}

		@Override
		public void voerUit(String par1, String par2) {
			HotelTUI.this.ended = true;
		}
    }
}